package com.csproj.dispatch.resource;

import com.codahale.metrics.annotation.Timed;
import com.csproj.dispatch.service.DispatchService;
import com.csproj.dispatch.service.dto.DispatchDTO;
import com.csproj.dispatch.util.entity.ArriveTimeCount;
import com.csproj.dispatch.util.entity.DispatchRouteParam;
import com.csproj.siiat.base.common.dto.BaseDTO;
import com.csproj.siiat.config.Languagesproperties;
import com.csproj.system.domain.Language;
import com.csproj.system.domain.UserInfo;
import com.csproj.system.repository.LanguageRepository;
import com.csproj.system.service.SysLogsService;
import com.csproj.system.service.UserInfoService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.poi.hssf.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.ZonedDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * REST controller for managing Dispatch.
 * 调度Controller
 */
@RestController
@RequestMapping("/api/center/dpr")
public class DispatchResource {

    private final Logger log = LoggerFactory.getLogger(DispatchResource.class);

    private static final String ENTITY_NAME = "dispatch";

    private final DispatchService dispatchService;
    private final UserInfoService userInfoService;
    private final SysLogsService sysLogsService;
    private final LanguageRepository languageRepository;
    private final Languagesproperties languagesproperties;

    public DispatchResource(DispatchService dispatchService, UserInfoService userInfoService, SysLogsService sysLogsService, LanguageRepository languageRepository, Languagesproperties languagesproperties) {
        this.dispatchService = dispatchService;
        this.sysLogsService = sysLogsService;
        this.userInfoService = userInfoService;
        this.languageRepository = languageRepository;
        this.languagesproperties = languagesproperties;
    }

    /**
     * 开启一次调度-为集装箱创建路径
     *
     * @param containerId 集装箱主键
     * @return
     */
    @PostMapping("/dispatch/{containerId}")
    @Timed
    public BaseDTO startDispatch(@RequestBody DispatchDTO dispatchDTO, @PathVariable String containerId) {
        UserInfo userInfo = userInfoService.getCurrentUser();
        sysLogsService.saveForGet("", userInfo.getName() + ":user_create_dispatch", "");
        return dispatchService.startDispatch(containerId, dispatchDTO);
    }

    /**
     * 获取全部调度信息-分页
     *
     * @param page   当前页码
     * @param limit  每页条数
     * @param option 查询条件(可选)
     * @return
     */
    @GetMapping("/dispatch")
    @Timed
    public BaseDTO searchAllDispatchPage(@RequestParam("page") Integer page, @RequestParam("limit") Integer limit
            , @RequestParam(value = "option", required = false) String option) {
        ObjectMapper mapper = new ObjectMapper();
        Map map = null;
        if (option != null && !"".equals(option)) {
            try {
                map = mapper.readValue(option, Map.class);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        UserInfo userInfo = userInfoService.getCurrentUser();
        sysLogsService.saveForGet("", userInfo.getName() + ":user_view_dispatch_list", "");
        return dispatchService.searchAllDispatchPage(page, limit, map);
    }

    /**
     * 获取全部调度信息-分页
     *
     * @param page   当前页码
     * @param limit  每页条数
     * @param option 查询条件(可选)
     * @return
     */
    @GetMapping("/dispatch/export")
    @Timed
    public void searchAllDispatchPageExport(HttpServletResponse response, @RequestParam("page") Integer page, @RequestParam("limit") Integer limit
            , @RequestParam(value = "option", required = false) String option) {
        ObjectMapper mapper = new ObjectMapper();
        Map map = null;
        if (option != null && !"".equals(option)) {
            try {
                map = mapper.readValue(option, Map.class);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

//        UserInfo userInfo = userInfoService.getCurrentUser();
//        sysLogsService.saveForGet("", userInfo.getName()+":user_view_dispatch_list","");
        List<DispatchDTO> list = dispatchService.searchAllDispatchExport(map);

        String container_no = "";
        String path_no = "";
        String pda_no = "";
        String lockset_no = "";
        String car_no = "";
        String start_site = "";
        String end_site = "";
        String time_of_shipment = "";
        String expected_arrived_time = "";
        String real_arrived_time = "";
        String container_state = "";
        String cargo_information = "";
        String logistics_information = "";
        String warn_info = "";

        Map<String, Object> currentMp = new HashMap<String, Object>() {
        };
        List<Language> l = languageRepository.findByDefault();
        Language first = null;
        if (l.size() > 0) {
            first = l.get(0);
        }

        if (first != null) {
            if (first.getName().equals("zh")) {
                currentMp = languagesproperties.getZh();
            } else if (first.getName().equals("en")) {
                currentMp = languagesproperties.getEn();

            } else if (first.getName().equals("pu")) {
                currentMp = languagesproperties.getPu();
            }

            if (currentMp != null) {
                container_no = currentMp.get("container_no").toString();
                path_no = currentMp.get("path_no").toString();
                pda_no = currentMp.get("pda_no").toString();
                lockset_no = currentMp.get("lockset_no").toString();
                car_no = currentMp.get("car_no").toString();
                start_site = currentMp.get("start_site").toString();
                end_site = currentMp.get("end_site").toString();
                time_of_shipment = currentMp.get("time_of_shipment").toString();
                expected_arrived_time = currentMp.get("expected_arrived_time").toString();
                real_arrived_time = currentMp.get("real_arrived_time").toString();
                container_state = currentMp.get("container_state").toString();
                cargo_information = currentMp.get("cargo_information").toString();
                logistics_information = currentMp.get("logistics_information").toString();

            }
        }

        String[] headers = {container_no, path_no, pda_no, lockset_no, car_no, start_site, end_site, time_of_shipment, expected_arrived_time, container_state, cargo_information, logistics_information, warn_info};

        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = workbook.createSheet();
        //设置列宽
        sheet.setDefaultColumnWidth((short) 18);
        //创建第一行的对象，第一行一般用于填充标题内容。从第二行开始一般是数据
        HSSFRow row = sheet.createRow(0);
        for (
                short i = 0;
                i < headers.length; i++) {
            //创建单元格，每行多少数据就创建多少个单元格
            HSSFCell cell = row.createCell(i);
            HSSFRichTextString text = new HSSFRichTextString(headers[i]);
            //给单元格设置内容
            cell.setCellValue(text);
        }

        //遍历集合，将每个集合元素对象的每个值填充到单元格中
        for (
                int i = 0; i < list.size(); i++) {
            DispatchDTO item = list.get(i);
            //从第二行开始填充数据
            row = sheet.createRow(i + 1);

            HSSFCell cell = row.createCell(0);
            cell.setCellValue(item.getContainerCode());
            HSSFCell cell1 = row.createCell(1);
            cell1.setCellValue(item.getRouteCode());
            HSSFCell cell2 = row.createCell(2);
            cell2.setCellValue(item.getHandsetCode());
            HSSFCell cell3 = row.createCell(3);
            cell3.setCellValue(item.getLockCode());
            HSSFCell cell4 = row.createCell(4);
            cell4.setCellValue(item.getPlatenumber());
            HSSFCell cell5 = row.createCell(5);
            cell5.setCellValue(item.getLaunchsiteName());
            HSSFCell cell6 = row.createCell(6);
            cell6.setCellValue(item.getDestinationsiteName());
            HSSFCell cell7 = row.createCell(7);
            if (item.getLaunchTime() != null) {
                cell7.setCellValue(item.getLaunchTime().toString());
            }


            HSSFCell cell8 = row.createCell(8);
            if (item.getExpectedarriveTime() != null) {
                cell8.setCellValue(item.getExpectedarriveTime().toString());
            }
            HSSFCell cell9 = row.createCell(9);
            if (item.getArriveTime() != null)
                cell9.setCellValue(item.getArriveTime().toString());
            HSSFCell cell10 = row.createCell(10);
            cell10.setCellValue(item.getContainerStatusName());


        }
        response.setContentType("application/octet-stream");
        response.setHeader("Content-disposition", "attachment;filename=" + "export.xls");//Excel文件名
        try {
            response.flushBuffer();
        } catch (
                IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //将workbook中的内容写入输出流中
        try {
            workbook.write(response.getOutputStream());
        } catch (
                IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 箱锁绑定
     *
     * @param containerCode 集装箱编号
     * @param platenumber   车牌号
     * @param lockCode      关锁编号
     * @param handsetCode   手持机编号
     * @param postionLat    纬度
     * @param postionLng    经度
     * @return
     */
    @PutMapping("/dispatch/bind")
    public BaseDTO bindContainerWithLock(@RequestParam(value = "containerCode", required = true) String containerCode,
                                         @RequestParam(value = "lockCode", required = true) String lockCode,
                                         @RequestParam(value = "platenumber", required = false) String platenumber,
                                         @RequestParam("handsetCode") String handsetCode,
                                         @RequestParam("postionLng") Double postionLng,
                                         @RequestParam("postionLat") Double postionLat) {
        return dispatchService.bindContainerWithLock(containerCode, lockCode, platenumber, handsetCode, postionLng, postionLat);
    }

    /**
     * @param containerCode
     * @param lockCode
     * @param postionLng
     * @param postionLat
     * @return
     */
    @PutMapping("/dispatch/unbind")
    public BaseDTO unBlock(@RequestParam(value = "containerCode", required = true) String containerCode,
                           @RequestParam(value = "lockCode", required = true) String lockCode,
                           @RequestParam("postionLng") Double postionLng,
                           @RequestParam("postionLat") Double postionLat) {

        return dispatchService.unBlock(containerCode, lockCode, postionLng, postionLat);
    }

    /**
     * 根据条件查询调度路径-在途监控
     *
     * @return
     */
    @GetMapping("/dispatchroute")
    public BaseDTO searchRoutesByCond(Integer page, Integer limit,
                                      @RequestParam(value = "siteid", required = false) String siteid,
                                      @RequestParam(value = "lockId", required = false) String lockId,
                                      @RequestParam(value = "lockstatus", required = false) String lockstatus,
                                      @RequestParam(value = "startTime", required = false) ZonedDateTime startTime,
                                      @RequestParam(value = "endTime", required = false) ZonedDateTime endTime) {

        UserInfo userInfo = userInfoService.getCurrentUser();
        sysLogsService.saveForGet("", userInfo.getName() + ":view_history_path", "");
        return dispatchService.searchRoutesByCond(new DispatchRouteParam(page, limit, siteid,
                lockstatus, lockId, startTime, endTime));
    }

    /**
     * 通过起始-到达仓储获取历史路径
     *
     * @param startCompanyId 起始仓储公司
     * @param endCompanyId   目的仓储公司
     * @return
     */
    @GetMapping("/dispatchhistory")
    public BaseDTO searchHistoryByCompany(String startCompanyId, String endCompanyId) {

        return dispatchService.searchHistoryByCompany(startCompanyId, endCompanyId);
    }


    /**
     * 通过起始-到达仓储获取历史路径
     *
     * @param startSiteId
     * @param endSiteId
     * @param startCompanyId 起始仓储公司
     * @param endCompanyId   目的仓储公司
     * @return
     */
    @GetMapping("/dispatchhistorynew")
    public BaseDTO searchHistoryBySiteOrCompany(String startSiteId, String endSiteId, String startCompanyId, String endCompanyId) {
        return dispatchService.searchHistoryBySiteOrCompany(startSiteId, endSiteId, startCompanyId, endCompanyId);
    }

    /**
     * 获取调度历史路径
     *
     * @param dispatchId 调度ID
     * @return
     */
    @GetMapping("/historyposition")
    public BaseDTO searchHistoryPoisitionById(String dispatchId) {
        return dispatchService.searchHistoryPoisitionById(dispatchId);
    }


    /**
     * 通过集装箱编号获取在途的调度信息
     *
     * @param containerCode 集装箱编号
     * @return
     */
    @GetMapping("/dispatchcontainer")
    public BaseDTO searchDispatchByContainerId(String containerCode) {
        return dispatchService.searchDispatchByContainerId(containerCode);
    }

    /**
     * 通过集装箱编号获取在途的调度信息
     *
     * @param lockNo 集装箱编号
     * @return
     */
    @GetMapping("/dispatchlocknum")
    public BaseDTO searchDispatchByLockNo(String lockNo) {
        return dispatchService.searchDispatchByLockNo(lockNo);
    }


    /**
     * 获取所有的未施封的调度
     *
     * @return
     */
    @GetMapping("/dispatchofunbind")
    public BaseDTO searchDispatchOfUnBind() {
        return dispatchService.searchDispatchOfUnBind();
    }


    /**
     * 获取所有的在途的的调度
     *
     * @return
     */
    @GetMapping("/dispatchofbind")
    public BaseDTO searchDispatchOfBind(String lockCode) {
        return dispatchService.searchDispatchOfBind(lockCode);
    }


    /**
     * 获取路径平均使用时间
     *
     * @param routerId
     * @return
     */
    @GetMapping("/dispatchavgtime")
    @Timed
    public BaseDTO searchRouterAvgTime(String routerId) {
        return dispatchService.searchRouterAvgTime(routerId);
    }

}